package com.coder4j.starter.mybatis.provider;

import com.alibaba.fastjson.JSON;
import com.coder4j.starter.mybatis.BaseQuery;
import com.coder4j.starter.mybatis.SqlFieldReader;
import com.coder4j.starter.tools.util.Console;
import com.coder4j.starter.tools.util.StringUtils;
import com.coder4j.starter.tools.vo.BaseException;

/**
 * 基础的Select提供类
 *
 * @author Keller
 * @date 2019-07-12 15:44:55
 */
public class BaseSelectProvider {

    /**
     * 根据ID 查询数据
     *
     * @return SELECT id,name... FROM route WHERE id = #{id}
     */
    public static <T> String selectById(ProviderVO<T> providerVO) {
        String tableName = providerVO.getTableName();
        T entity = providerVO.getEntity();
        String sql = getSelectPrefix(tableName, entity) + " WHERE id = #{id}";
        Console.info("selectById", tableName, sql, providerVO.getId());
        return sql;
    }

    /**
     * 根据ID列表查询
     *
     * @param providerVO
     * @param <T>
     * @return
     */
    public static <T> String selectByIds(ProviderVO<T> providerVO) {
        String tableName = providerVO.getTableName();
        T entity = providerVO.getEntity();
        String sql = "<script>"
                + getSelectPrefix(tableName, entity)
                + " WHERE id IN "
                + "<foreach collection='idList' item='item' index='index' open='(' separator=',' close=')'>"
                + " #{item}"
                + "</foreach>"
                + "</script>";
        Console.info("selectByIds", tableName, sql, providerVO.getIdList());

        return sql;
    }

    /**
     * 查询列表
     *
     * @param <K>
     * @return
     */
    public static <T, K extends BaseQuery<T>> String selectList(K query) {
        String sql;
        String tableName = query.getDefaultAliasTableName();
        T entity = query.getEntityInstance();

        String condition = SqlFieldReader.getDynamicTableCondition(query);
        sql = "<script>"
                + getSelectPrefixWithAliasTableName(tableName, entity)
                + condition
                + SqlFieldReader.getDefaultOrder(query)
                + "</script>";

        Console.info("selectList", tableName, sql, JSON.toJSONString(query));
        return sql;
    }

    /**
     * 分页查询
     *
     * @param query
     * @return SELECT id,name... FROM router  WHERE name = #{name} AND serviceName = #{serviceName}  ORDER BY createTime ASC LIMIT #{startRows},#{size}
     */
    public static <T, K extends BaseQuery<T>> String selectPageList(K query) {
        String sql;
        String tableName = query.getDefaultAliasTableName();
        T entity = query.getEntityInstance();

        String condition = SqlFieldReader.getDynamicTableCondition(query);
        sql = "<script>" + getSelectPrefixWithAliasTableName(tableName, entity)
                + condition
                + SqlFieldReader.getDefaultOrder(query)
                + " LIMIT #{offset},#{size} </script>";

        Console.info("selectPageList", tableName, sql, JSON.toJSONString(query));
        return sql;
    }

    /**
     * 根据条件查询记录总数
     *
     * @param query
     * @param <T>
     * @return SELECT COUNT(1) FROM router WHERE name = #{name} AND serviceName = #{serviceName}
     */
    public static <T, K extends BaseQuery<T>> String selectCount(K query) {
        String tableName = query.getDefaultAliasTableName();
        String sql = "<script> SELECT COUNT(1) FROM "
                + tableName
                + SqlFieldReader.getDynamicTableCondition(query)
                + "</script>";
        Console.info("selectCount", tableName, sql, JSON.toJSONString(query));
        return sql;
    }


    /**
     * 获取通用查询前缀
     *
     * @param entity 实体类类型
     * @return SELECT 所有字段 FROM 表名
     */
    private static <T> String getSelectPrefix(String tableName, T entity) {
        return "SELECT " + StringUtils.humpToLine(SqlFieldReader.getFieldStr(entity))
                + " FROM " + tableName + " ";
    }

    private static <T> String getSelectPrefixWithAliasTableName(String tableName, T entity) {
        return "SELECT " + StringUtils.humpToLine(SqlFieldReader.getFieldStrWithAliasTableName(entity))
                + " FROM " + tableName + " ";
    }
}
